package com.sec.android.app.myfiles.log;

import android.content.Context;
import android.text.TextUtils;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.local.category.CategoryFileRecord;

import java.util.Calendar;
import java.util.Locale;

/**
 * Log interface class
 *
 * @author jae.bae
 */
public class Log {
    //private static final boolean REAL = !android.os.Debug.semIsProductDev();
    private static final boolean REAL = false;

    private static final int MAX_INDEX = 9999;
    private static final String MY_FILES_TAG = "myFiles";
    private static final String USER_ACTION_TAG = "UA";
    private static final String SLUGGISH_TAG = "VerificationLog";
    private static int mLogIndex = 0;
    private static int sLogLevel = android.util.Log.VERBOSE;

    public static final String GATE_TAG = "GATE";
    public static final String GATE_TAG_S = "<GATE-M>";
    public static final String GATE_TAG_E = "</GATE-M>";

    public enum SluggishType {
        OnCreate,
        OnResume,
        Execute
    }

    /**
     * Prohibit create class
     */
    private Log() {
    }

    static {
        if (REAL) {
            sLogLevel = android.util.Log.ERROR;
        } else {
            sLogLevel = android.util.Log.VERBOSE;
        }
    }

    private static int getLogIndex() {
        mLogIndex++;

        if (mLogIndex > MAX_INDEX) {
            mLogIndex = 0;
        }

        return mLogIndex;
    }

    private static String getMsg(Object obj, String msg, boolean isUserAction) {
        String tag = null;

        if (obj != null) {
            tag = obj.getClass().getSimpleName();
        }

        return getMsg(tag, msg, isUserAction);
    }

    private static String getMsg(String tag, String msg, boolean isUserAction) {
        StringBuilder sb = new StringBuilder();

        if (tag != null) {
            if (isUserAction) {
                sb.append(String.format(Locale.getDefault(), "[%04d/%-20s/%s] ", getLogIndex(), tag, USER_ACTION_TAG));
            } else {
                sb.append(String.format(Locale.getDefault(), "[%04d/%-20s] ", getLogIndex(), tag));
            }
        } else {
            sb.append(String.format(Locale.getDefault(), "[%04d] ", getLogIndex()));
        }

        sb.append(msg);
        return sb.toString();
    }

    public static void g(String msg) {
        /*
        if (SemGateConfig.isGateEnabled()) {
            android.util.Log.i(GATE_TAG, gateLogMsg(msg));
        }
        */
    }

    public static void v(String tag, String msg) {
        if (sLogLevel <= android.util.Log.VERBOSE) {
            android.util.Log.v(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void d(String tag, String msg) {
        if (sLogLevel <= android.util.Log.DEBUG) {
            android.util.Log.d(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void i(String tag, String msg) {
        if (sLogLevel <= android.util.Log.INFO) {
            android.util.Log.i(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void w(String tag, String msg) {
        if (sLogLevel <= android.util.Log.WARN) {
            android.util.Log.w(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void e(String tag, String msg) {
        if (sLogLevel <= android.util.Log.ERROR) {
            android.util.Log.e(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void a(String tag, String msg) {
        if (sLogLevel <= android.util.Log.INFO) {
            android.util.Log.i(MY_FILES_TAG, getMsg(tag, msg, false));
        }
    }

    public static void v(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.VERBOSE) {
            android.util.Log.v(MY_FILES_TAG, getMsg(obj, msg, false));
        }
    }

    public static void d(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.DEBUG) {
            android.util.Log.d(MY_FILES_TAG, getMsg(obj, msg, false));
        }
    }

    public static void i(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.INFO) {
            android.util.Log.i(MY_FILES_TAG, getMsg(obj, msg, false));
        }
    }

    public static void w(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.WARN) {
            android.util.Log.w(MY_FILES_TAG, getMsg(obj, msg, false));
        }
    }

    public static void e(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.ERROR) {
            android.util.Log.e(MY_FILES_TAG, getMsg(obj, msg, false));
        }
    }

    public static void a(Object obj, String msg) {
        if (sLogLevel <= android.util.Log.INFO) {
            android.util.Log.i(MY_FILES_TAG, getMsg(obj, msg, true));
        }
    }

    public static void sluggish(SluggishType type) {
        String msg = null;
        switch (type) {
            case OnCreate:
                msg = "onCreate";
                break;
            case OnResume:
                msg = "onResume";
                break;
            case Execute:
                msg = "Executed";
                break;
        }

        if (msg != null) {
            android.util.Log.i(SLUGGISH_TAG, msg);
        }
    }

    public static String gateLogMsg(String msg) {
        String ret = GATE_TAG_S;
        ret += msg;
        ret += GATE_TAG_E;

        return ret;
    }

    public static void loggingForChinaTest(Context context, FileRecord record) {
        String chinaLog = "ctaifs";         //This is formal Log TAG. (Check with PL or SRC-Beijing)
        String functionName = null;
        String operation = null;
        CategoryFileRecord fileRecord;

        if (record instanceof CategoryFileRecord) {
            fileRecord = (CategoryFileRecord) record;

            if (FileRecord.CategoryType.Image.equals(fileRecord.getCategoryType())) {
                functionName = "读取图片"; // read image
                operation = "打开图像类别"; // open the image category
            } else if (FileRecord.CategoryType.Video.equals(fileRecord.getCategoryType())) {
                functionName = "读取视频"; // read video
                operation = "打开视频类别"; // open the video category
            } else if (FileRecord.CategoryType.Audio.equals(fileRecord.getCategoryType())) {
                functionName = "读取音频"; // read audio
                operation = "打开音频类别"; // open the audio category
            }
        } else {
            return;
        }

        String appName = context.getString(R.string.app_name);
        String timeStr = getNewTimestamp();

        if (!TextUtils.isEmpty(functionName)) {
            //LOG FORMAT:  Time <Chinese name of the APP>[keywords][Process name]:[Function name] Operations.. parameters
            String cttlLog = timeStr + " <" + appName + " >[" + appName + "][" + context.getPackageName() + "]:[" + functionName + "] " + operation;
        }
    }

    private static String getNewTimestamp() {
        Calendar c = Calendar.getInstance();
        return android.text.format.DateFormat.format("[yyyy-MM-dd HH:mm:ss]", c.getTime()).toString();
    }

    public static String getEncodedMsg(String msg) {
        if (TextUtils.isEmpty(msg)) {
            return "";
        }

        char[] encodedMsg = new char[msg.length()];

        char b4 = 16;
        char b3 = 8;
        char b1 = 2;
        char b0 = 1;

        char b0mask = 254;
        char b1mask = 253;
        char b3mask = 247;
        char b4mask = 239;

        char a, b;

        for (int i = 0; i < msg.length(); i++) {
            b = a = msg.charAt(i);

            if ((a & b1) != 0) {
                b = (char) (b | b0);
            } else {
                b = (char) (b & b0mask);
            }

            if ((a & b0) != 0) {
                b = (char) (b | b1);
            } else {
                b = (char) (b & b1mask);
            }

            if ((a & b4) != 0) {
                b = (char) (b | b3);
            } else {
                b = (char) (b & b3mask);
            }

            if ((a & b3) != 0) {
                b = (char) (b | b4);
            } else {
                b = (char) (b & b4mask);
            }
            encodedMsg[i] = b;
        }

        return String.copyValueOf(encodedMsg);
    }
}
